package org.millioncall.yueyoga.common.utils;

import java.io.File;
import java.io.IOException;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.util.WebUtils;

//Last modified by zangjy on 2012-3-31
public class CosMultipartResolver implements MultipartResolver, ServletContextAware {
	public static final String MULTIPART_CONTENT_TYPE = "multipart/form-data";
	protected final Logger logger = LoggerFactory.getLogger(getClass());
	private int maxUploadSize = Integer.MAX_VALUE;// 最大可上传字节数
	private String defaultEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;// 编码
	private File uploadTempDir;// 临时上传目录

	public CosMultipartResolver() {
	}

	public CosMultipartResolver(ServletContext servletContext) {
		this.uploadTempDir = WebUtils.getTempDir(servletContext);
	}

	public void setMaxUploadSize(int maxUploadSize) {
		this.maxUploadSize = maxUploadSize;
	}

	protected int getMaxUploadSize() {
		return maxUploadSize;
	}

	public void setDefaultEncoding(String defaultEncoding) {
		this.defaultEncoding = defaultEncoding;
	}

	protected String getDefaultEncoding() {
		return defaultEncoding;
	}

	public void setUploadTempDir(Resource uploadTempDir) throws IOException {
		if(!uploadTempDir.exists() && !uploadTempDir.getFile().mkdirs()) {
			throw new IllegalArgumentException("Given uploadTempDir [" + uploadTempDir + "] could not be created");
		}
		this.uploadTempDir = uploadTempDir.getFile();
	}

	protected File getUploadTempDir() {
		return uploadTempDir;
	}

	public void setServletContext(ServletContext servletContext) {
		if(this.uploadTempDir == null) {
			this.uploadTempDir = WebUtils.getTempDir(servletContext);
		}
	}

	// 是否为文件上传表单multipart/form-data
	public boolean isMultipart(HttpServletRequest request) {
		return request.getContentType() != null && request.getContentType().startsWith(MULTIPART_CONTENT_TYPE);
	}

	// 处理文件表单请求
	public MultipartHttpServletRequest resolveMultipart(HttpServletRequest request) throws MultipartException {
		try {
			CosMultipartRequest multipartRequest = newMultipartRequest(request);
			if(logger.isDebugEnabled()) {
				Set<String> fileNames = multipartRequest.getFileNames();
				for(String fileName : fileNames) {
					File file = multipartRequest.getFile(fileName);
					logger.debug("Found multipart file '" + fileName + "' of size " + (file != null ? file.length() : 0) + " bytes with original filename ["
							+ multipartRequest.getOriginalFileName(fileName) + "]" + (file != null ? "stored at [" + file.getAbsolutePath() + "]" : "empty"));
				}
			}
			return new CosMultipartHttpServletRequest(request, multipartRequest);
		} catch (IOException ex) {
			if(ex.getMessage().indexOf("exceeds limit") != -1) {
				throw new MaxUploadSizeExceededException(this.maxUploadSize, ex);
			} else {
				throw new MultipartException("Could not parse multipart request", ex);
			}
		}
	}

	// 创建一个文件上传请求
	protected CosMultipartRequest newMultipartRequest(HttpServletRequest request) throws IOException {
		String tempPath = this.uploadTempDir.getAbsolutePath();
		String enc = determineEncoding(request);
		return new CosMultipartRequest(request, tempPath, this.maxUploadSize, enc);
	}

	// 确认上传编码
	protected String determineEncoding(HttpServletRequest request) {
		String enc = request.getCharacterEncoding();
		if(enc == null) {
			enc = this.defaultEncoding;
		}
		return enc;
	}

	public void cleanupMultipart(MultipartHttpServletRequest request) {
		CosMultipartRequest multipartRequest = ((CosMultipartHttpServletRequest)request).getMultipartRequest();
		Set<String> fileNames = multipartRequest.getFileNames();
		for(String fileName : fileNames) {
			File file = multipartRequest.getFile(fileName);
			if(file != null) {
				if(file.exists()) {
					if(file.delete()) {
						if(logger.isDebugEnabled()) {
							logger.debug("Cleaned up multipart file '" + fileName + "' with original filename [" + multipartRequest.getOriginalFileName(fileName) + "], stored at ["
									+ file.getAbsolutePath() + "]");
						}
					} else {
						logger.warn("Could not delete multipart file '" + fileName + "' with original filename [" + multipartRequest.getOriginalFileName(fileName) + "], stored at ["
								+ file.getAbsolutePath() + "]");
					}
				} else {
					if(logger.isDebugEnabled()) {
						logger.debug("Multipart file '" + fileName + "' with original filename [" + multipartRequest.getOriginalFileName(fileName) + "] has already been moved - no cleanup necessary");
					}
				}
			}
		}
	}
}